package com.taomus.mytools.simplec;

import com.taomus.mytools.simplec.generate.Token;
import com.taomus.mytools.simplec.generate.WordEnum;

public final class Lex {
	private char[] source;
	private int i = 0;
	public Lex(final char[] inSource){
		this.source = inSource;
	}
	private char getChar(){
		char c = '#';
		if(i < source.length){
			c = source[i++];
		}
		return c;
	}
	private char getChar(int offset){
		char c = '#';
		if(i+offset < source.length){
			c = source[i+offset];
		}
		return c;
	}
	boolean isDebug = false;
	public Token getToken(){
		char sym = getChar();
		if(isDebug ){
			System.err.println((int)sym);
		}
		if(sym == 32 || sym == '\t'){
			do{
				sym = getChar();
			} while(sym == 32 ||sym == '\t');
		}
		switch(sym){
		case '#':
			return new Token(WordEnum.EOF);
		case '\n':
			sym = getChar(0);
			while(sym == '\n'){
				sym = getChar();
			}
			return new Token(WordEnum.ROW);
		case '+':
			return new Token(WordEnum.ADD);
		case '*':
			return new Token(WordEnum.MUL);
		case '/':
			return new Token(WordEnum.DIV);
		case '-':
			return new Token(WordEnum.SUB);
		case '%':
			return new Token(WordEnum.MOD);
		case '{':
			return new Token(WordEnum.FUNCL);
		case '}':
			return new Token(WordEnum.FUNCR);
		case '(':
			return new Token(WordEnum.LP);
		case ')':
			return new Token(WordEnum.RP);
		case ',':
			return new Token(WordEnum.SPLIT);
		case '=':
			char follow = getChar(0);
			if('=' == follow){
				getChar();
				return new Token(WordEnum.EQ);
			}
			return new Token(WordEnum.VAR);
		case '>':
			follow = getChar(0);
			if('=' == follow){
				getChar();
				return new Token(WordEnum.GE);
			}
			return new Token(WordEnum.GT);
		case '<':
			follow = getChar(0);
			if('=' == follow){
				getChar();
				return new Token(WordEnum.LE);
			}
			return new Token(WordEnum.LT);
		case '?':
			follow = getChar(0);
			if('.' == follow){
				getChar();
				return new Token(WordEnum.IFEND);
			}
			return new Token(WordEnum.IF);
		case '!':
			follow = getChar(0);
			if('=' == follow){
				getChar();
				return new Token(WordEnum.NE);
			}
			return new Token(WordEnum.IFELSE);
		case ':':
			follow = getChar(0);
			if('=' == follow){
				getChar();
				return new Token(WordEnum.MOV);
			}
			//TODO error
			return new Token(WordEnum.ERR);
		default:
			return getKeyWord(sym);
		}
	}
	private Token getKeyWord(char sym){
		StringBuilder symbol = new StringBuilder();
		if('\'' == sym || '\"' == sym){
			char beginSym = sym;
			int count =0;
			do{
				sym = getChar();
				if(sym == beginSym){
					break;
				}
				symbol.append(sym);
				count += 1;
			}while(sym != beginSym);
			switch(count){
			case 0:
				return new Token(WordEnum.CHAR,"");
			case 1:
				return new Token(WordEnum.CHAR,symbol.toString());
			default:
				return new Token(WordEnum.STRING,symbol.toString());
			}
		}
		if('@' == sym){
			sym = getChar();
			if(Character.isDigit(sym)){
				symbol.append("@");
				do{
					symbol.append(sym);
					sym = getChar();
				}while(Character.isDigit(sym));
				return new Token(WordEnum.FAGRS,symbol.toString());
			}
			return new Token(WordEnum.FAGRS);
		}
		if(Character.isLetter(sym) || '.' == sym || '_' == sym){
			do{
				symbol.append(sym);
				sym = getChar();
			}while(Character.isLetter(sym)||
					Character.isDigit(sym)||'.' == sym || '_' == sym);
			/*Token temp = Word.getKeyWordToken(symbol.toString());
			if(temp != null){
				return temp;
			}*/
			i--;
			return new Token(WordEnum.ID,symbol.toString());
		}
		if(Character.isDigit(sym)){
			do{
				symbol.append(sym);
				sym = getChar();
			}while(Character.isDigit(sym));
			if(sym == '.'){
				do{
					symbol.append(sym);
					sym = getChar();
				}while(Character.isDigit(sym));
				i--;
				return new Token(WordEnum.DECIMAL,symbol.toString());
			}
			i--;
			return new Token(WordEnum.NUMBER,symbol.toString());
		}
		return new Token(WordEnum.EOF);
	}
}
